﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.UI;


namespace jNET.Controls
{
    public class CustomBoundField : BoundColumn
    {
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Browsable(true), Description("The name to identify column, used for event client handler.")]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string UniqueName
        {
            get;
            set;
        }
    }

    public class CustomTemplateField : TemplateColumn
    {
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Browsable(true), Description("The name to identify column, used for event client handler.")]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string UniqueName
        {
            get;
            set;
        }
    }
   
    public class SelectTemplate : ITemplate
    {
        string chkID;

        public SelectTemplate(string chkID)
        {
            this.chkID = chkID;
        }

        CheckBox chkSelect;

        public void InstantiateIn(Control container)
        {
            chkSelect = new CheckBox();
            chkSelect.ID = this.chkID;
            chkSelect.Attributes["class"] = chkID;
            container.Controls.Add(chkSelect);
        }
    }

    public class ServerSelectTemplate : ITemplate
    {
        string chkID;

        public ServerSelectTemplate(string chkID)
        {
            this.chkID = chkID;
        }

        CheckBox chkSelect;

        public void InstantiateIn(Control container)
        {
            chkSelect = new CheckBox();
            chkSelect.ID = this.chkID;
            chkSelect.Attributes["class"] = chkID;
            chkSelect.AutoPostBack = true;
            container.Controls.Add(chkSelect);
        }
    }

    public class ClientSelectField : TemplateColumn
    {
        public override void Initialize()
        {
            this.ItemTemplate = new SelectTemplate("select");
            this.HeaderTemplate = new SelectTemplate("selectAll");
            base.Initialize();
        }
    }

    public class ServerSelectField : TemplateColumn
    {
        public override void Initialize()
        {
            this.ItemTemplate = new ServerSelectTemplate("select");
            base.Initialize();
        }
    }

    public delegate void OnNeedDataSourceEventHandler(object sender, EventArgs e);

    public class CustomGridRowSelectedEventArgs : EventArgs
    {
        public int RowIndex
        {
            get;
            set;
        }
    }
    public delegate void OnRowSelectedEventHandler(object sender, CustomGridRowSelectedEventArgs e);

    public class CustomGrid: DataGrid
    {
        public event OnNeedDataSourceEventHandler NeedDataSource;
        private void OnNeedDataSource(EventArgs e)
        {
            if (NeedDataSource != null)
            {
                NeedDataSource(this, e);
                this.DataBind();
            }
        }

        public event OnRowSelectedEventHandler RowSelected;
        private void OnRowSelected(CustomGridRowSelectedEventArgs e)
        {
            if (RowSelected != null)
            {
                RowSelected(this, e);
            }
        }

        public void Rebind()
        {
            OnNeedDataSource(new EventArgs());
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Browsable(true), Description("Allow user to handle row click client event")]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string OnClientRowClick
        {
            get;
            set;
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Browsable(true), Description("Allow user to handle row click client event")]
        [PersistenceMode(PersistenceMode.Attribute)]
        public bool AllowRowSelect
        {
            get;
            set;
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Browsable(true), Description("Allow user to handle row click client event")]
        [PersistenceMode(PersistenceMode.Attribute)]
        public bool AllowRowMultiSelect
        {
            get;
            set;
        }

        protected override void OnItemCreated(DataGridItemEventArgs e)
        {
            base.OnItemCreated(e);
            if (e.Item is DataGridItem)
            {
                if (e.Item.ItemType == ListItemType.Footer)
                    e.Item.CssClass = "gridFooter";
                else if (e.Item.ItemType == ListItemType.Header)
                    e.Item.CssClass = "gridHeader";
                else
                    e.Item.CssClass = "gridRow";
                for (int i = 0; i < e.Item.Cells.Count; i++)
                {
                    if (this.Columns[i] is CustomBoundField && !string.IsNullOrEmpty(((CustomBoundField)this.Columns[i]).UniqueName))
                        e.Item.Cells[i].Attributes["UniqueName"] = ((CustomBoundField)this.Columns[i]).UniqueName;
                    else if (this.Columns[i] is ServerSelectField)
                    {
                        CheckBox chkSelect = (CheckBox)e.Item.FindControl("select");
                        if (chkSelect != null)
                        {
                            chkSelect.CheckedChanged += chkSelect_CheckedChanged;
                            if (!AllowRowSelect)
                                chkSelect.AutoPostBack = false;
                            chkSelect.Attributes["RowIndex"] = e.Item.ItemIndex.ToString();
                        }
                    }
                }
            }
        }

        public void chkSelect_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox chkSelect = (CheckBox)sender;
            int rowIndex = int.Parse(chkSelect.Attributes["RowIndex"]);
            
            CustomGridRowSelectedEventArgs arg = new CustomGridRowSelectedEventArgs();
            arg.RowIndex = rowIndex;
            SelectedIndex = rowIndex;
            OnRowSelected(arg);
        }

        protected override void OnItemDataBound(DataGridItemEventArgs e)
        {
            base.OnItemDataBound(e);

            if (e.Item is DataGridItem && e.Item.ItemIndex >= 0)
            {
                string json = "";
                if (DataKeys.Count > 0)
                {
                    json = "DataItem = {";
                        if (DataKeys[e.Item.DataSetIndex] is DateTime)
                            json += string.Format("'{0}':'\\/Date{1}\\/'",DataKeyField, ((DateTime)DataKeys[e.Item.DataSetIndex]).ToString("yyyy MM dd : HH:mm:ss"));
                        else if (DataKeys[e.Item.DataSetIndex] is int || DataKeys[e.Item.DataSetIndex] is decimal)
                            json += string.Format("'{0}':{1}", DataKeyField, DataKeys[e.Item.DataSetIndex]);
                        else if (DataKeys[e.Item.DataSetIndex] is bool)
                            json += string.Format("'{0}':{1}", DataKeyField, DataKeys[e.Item.ItemIndex].ToString().ToLower());
                        else
                            json += string.Format("'{0}':'{1}'", DataKeyField, DataKeys[e.Item.ItemIndex].ToString());
                    json += "}";
                    e.Item.Attributes["DataItem"] = json;

                    if (e.Item.ItemIndex == SelectedIndex)
                        e.Item.CssClass = "selectedRow";
                }
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.Attributes["AllowSelect"] = AllowRowSelect ? "true" : "false";
            this.Attributes["AllowRowMultiSelect"] = AllowRowMultiSelect ? "true" : "false";
            if(!string.IsNullOrEmpty(OnClientRowClick))
                this.Attributes["OnClientRowClick"] = OnClientRowClick.Trim();
            this.Attributes["SelectedValues"] = "";
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            ScriptManager.RegisterClientScriptInclude(this, typeof(Page), Guid.NewGuid().ToString(), this.ResolveUrl("~/scripts/CustomGrid.js"));
            ScriptManager.RegisterStartupScript(this, typeof(Page), Guid.NewGuid().ToString(), string.Format("var grid = new customGrid('{0}');grid.init();", ClientID), true); 
        }
    }
}